package com.login.framework.utils;

import java.io.File;
import java.io.FileInputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import com.login.framework.LoginConstants;
import com.login.framework.LoginFramework;

public class BlackListManager {

	private static final String ATTR_USERNAME = "username";

	private static final String NODE_USER = "user";

	private static final String ATTR_DATETIME = "datetime";

	private static final String BLACKLIST_PATH = "blacklist.xml";

	private static final String ROOT_TAG = "black-list";

	private Document blacklist;

	private static BlackListManager instance;

	public static BlackListManager get() {
		if (instance == null) {
			instance = new BlackListManager();
		}
		return instance;
	}

	private BlackListManager() {
		DocumentBuilderFactory docFactory = DocumentBuilderFactory
				.newInstance();
		DocumentBuilder docBuilder;
		try {
			docBuilder = docFactory.newDocumentBuilder();

			try {
				blacklist = docBuilder
						.parse(new FileInputStream(BLACKLIST_PATH));
			} catch (Exception e) {
				blacklist = docBuilder.newDocument();
				blacklist.appendChild(blacklist.createElement(ROOT_TAG));
			}

		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		}

	}

	public void addUser(String username) {
		try {

			Element root = (Element) blacklist.getElementsByTagName(ROOT_TAG)
					.item(0);

			Element user = blacklist.createElement(NODE_USER);
			user.setAttribute(ATTR_USERNAME, username);

			user.setAttribute(ATTR_DATETIME, new SimpleDateFormat(
					LoginConstants.DATE_TIME_FORMAT).format(new Date()));
			root.appendChild(user);

			TransformerFactory transformerFactory = TransformerFactory
					.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			DOMSource source = new DOMSource(blacklist);
			StreamResult result = new StreamResult(new File(BLACKLIST_PATH));
			transformer.transform(source, result);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public boolean isUserBlackListed(String username) {

		try {
			XPath xpath = XPathFactory.newInstance().newXPath();

			XPathExpression expr = xpath.compile(String.format(
					"//user[@username='%s']", username));

			NodeList result = (NodeList) expr.evaluate(blacklist,
					XPathConstants.NODESET);

			if (result != null && result.getLength() > 0) {

				for (int i = 0; i < result.getLength(); i++) {
					Element user = (Element) result.item(i);
					Date date = new SimpleDateFormat(
							LoginConstants.DATE_TIME_FORMAT).parse(user
							.getAttribute(ATTR_DATETIME));
					Calendar c = Calendar.getInstance();
					c.setTime(date);
					c.add(Calendar.MINUTE, LoginFramework.get().getConfig()
							.blackListTimeInMinutes());
					if (new Date().before(c.getTime())) {
						return true;
					}
				}
			}

			return false;

		} catch (Exception e) {
			return false;
		}

	}

}
